﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using QMERP.Domain.Dtos;
using QMERP.Domain.Entities;
using QMERP.Domain.Enums;
using QMERP.Infrastructure.CustomException;
using QMERP.Infrastructure.EFCore;
using QMERP.Infrastructure.EFCore.Extensions;
using QMERP.Infrastructure.Extensions;
using QMERP.Infrastructure.Security;
using QMERP.Infrastructure.Tools;

namespace QMERP.Application.Services
{
    public class PrivilegeService: IPrivilegeService
    {
        private readonly IMapper _mapper;
        private readonly ICurrentUser _currentUser;
        private readonly QMERPDbContext _db;
        public PrivilegeService(IMapper mapper, QMERPDbContext db, ICurrentUser currentUser)
        {
            _mapper = mapper;
            _db = db;
            _currentUser = currentUser;
        }
        /// <summary>
        /// 获取当前用户的许可证列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<string>> GetCurrentUserLicenses()
        {
            List<string> licenses = new();
            //如果是管理员
            if (_currentUser.IsAdmin == true)
            {
                licenses = await _db.App.Where(x => x.License != null && x.License != "").Select(x => x.License!).ToListAsync();
            }
            else
            {
                //获取用户
                var user = await _db.User.Include(x => x.User_Roles).Include(x => x.User_Organizations).FindByIdAsync(_currentUser.Id);
                if (user != null)
                {
                    //获取用户的组织机构
                    var organizationIds = user.User_Organizations.Select(s => s.OrganizationId).ToArray();
                    //获取用户的角色Ids
                    var userRoleIds = await _db.Role.GetByUserId(_currentUser.Id).Select(s => s.Id).ToArrayAsync();
                    //获取用户的组织机构的角色Ids
                    var organizationRoleIds = await _db.Role.GetByOrganizationIds(organizationIds!).Select(s => s.Id).ToArrayAsync();
                    //获取权限列表
                    List<Privilege> privilegeList = await _db.Privilege.GetByMasterValues(_currentUser.Id, organizationIds, userRoleIds, organizationRoleIds).ToListAsync();
                    //获取已授权的AppIds
                    long[] appIds = privilegeList.Where(x => x.Access == AccessEnum.App.ToString()).Select(s => s.AccessValue).ToArray();
                    //获取功能许可证列表
                    licenses = await _db.App.Where(x => appIds.Contains(x.Id) && x.License != null && x.License != "").Select(s => s.License!).ToListAsync();
                }
            }
            return licenses;
        }
        /// <summary>
        /// 获取当前用户的Privileges
        /// </summary>
        /// <returns></returns>
        public async Task<List<Privilege>> GetCurrentUserPrivileges()
        {
            //获取用户
            var user = await _db.User.Include(x => x.User_Roles).FindByIdAsync(_currentUser.Id);
            //获取用户的组织机构
            var organizationIds = user?.User_Organizations?.Select(s => s.OrganizationId).ToArray();
            organizationIds ??= Array.Empty<long>();
            //获取用户的角色Ids
            var userRoleIds = await _db.Role.GetByUserId(_currentUser.Id).Select(s => s.Id).ToArrayAsync();
            //获取用户的组织机构的角色Ids
            long[] organizationRoleIds = await _db.Role.GetByOrganizationIds(organizationIds).Select(s => s.Id).ToArrayAsync();
            //获取权限列表
            List<Privilege> privileges = await _db.Privilege.GetByMasterValues(_currentUser.Id, organizationIds, userRoleIds, organizationRoleIds).ToListAsync();
            return privileges;
        }
        /// <summary>
        /// 获取权限
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<List<PrivilegeResponse>> GetPrivileges(PrivilegeRequest request)
        {
            MasterEnum? master = request.Master.GetEnum<MasterEnum>();
            if (master == null)
                return new List<PrivilegeResponse>();
            //获取权限列表
            List<Privilege> privileges = await _db.Privilege.Get(master.Value, request.Id).ToListAsync();
            return _mapper.Map<List<PrivilegeResponse>>(privileges);
        }
        /// <summary>
        /// 设置权限
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task SetPrivilege(PrivilegeSetRequest request)
        {
            if (request.Id == ConfigurationUtils.GetSection("AdminRoleId").ToInt())
                throw new ApiException($"超级管理员不需设置权限!");

            MasterEnum? master = request.Master.GetEnum<MasterEnum>();
            if (master == null)
                return;
            List<Privilege> privileges = await _db.Privilege.Where(x => x.Master == master.ToString() && x.MasterValue == request.Id).ToListAsync();
            _db.RemoveRange(privileges);
            if (request.AppIds != null)
            {
                foreach (var appId in request.AppIds)
                {
                    Privilege model = new(master.Value, request.Id, AccessEnum.App, appId);
                    await _db.Privilege.AddAsync(model);
                }
            }
            if (request.ResourceIds != null)
            {
                foreach (var resourceId in request.ResourceIds)
                {
                    Privilege model = new(master.Value, request.Id, AccessEnum.Resource, resourceId);
                    await _db.Privilege.AddAsync(model);
                }
            }
            await _db.SaveChangesAsync();
        }
    }
}
